#pragma once
#include <iostream>
#include <vector>
#include <string>
#include <memory>
#include <sstream>
#include <functional>
#include <unordered_map>
#include "Command.h"
#include "ReMessage.h"
using namespace std;

static unordered_map<string,CommandType> const command_map  = {
    {"SET", CommandType::SET},
    {"GET", CommandType::GET},
    {"PING", CommandType::PING},
    {"ECHO", CommandType::ECHO},
    {"INFO",CommandType::INFO},
    {"REPLCONF",CommandType::REPLCONF},
    {"PSYNC",CommandType::PSYNC},
};

static unordered_map<string,ReMessageType> const remessage_map  = {
    {"PONG", ReMessageType::PONG},
    {"OK", ReMessageType::OK},
};

class Paraser
{
private:
    static vector<std::string> splitByDelimiter(const char* message, int len) {
        vector<std::string> result;
        stringstream ss(std::string(message, len));
        string item;
        char delimiter='\r';
        while (getline(ss, item,delimiter)) {
            if(item.size() && item.front()=='\n'){
                if(item.size()>=2 && item[1]!='$'){
                    item.erase(0,1);
                    result.push_back(item);
                }
            }

        }

        return result;
    }

    static unique_ptr<Command> parse_bulk_message(char* message,int len){
        //解析bulk格式的消息
        vector<string> args;
        unique_ptr<Command> command_ptr;
        message++;
        vector<string> tokens=Paraser::splitByDelimiter(message,len);
        for(int i=0;i<tokens.size();i++){
            auto it=command_map.find(tokens[i]);
            if(it!=command_map.end()){
                tokens.erase(tokens.begin(),tokens.begin()+i+1);
                switch (it->second)
                {
                case CommandType::SET:
                    command_ptr=make_unique<SetCommand>(tokens);
                    break;
                case CommandType::GET:
                    command_ptr=make_unique<GetCommand>(tokens);
                    break;
                case CommandType::PING:
                    command_ptr=make_unique<PingCommand>(tokens);
                    break;
                case CommandType::ECHO:
                    command_ptr=make_unique<EchoCommand>(tokens);
                    break;
                case CommandType::INFO:
                    command_ptr=make_unique<InfoCommand>(tokens);
                    break;
                case CommandType::REPLCONF:
                    command_ptr=make_unique<ReplConfCommand>(tokens);
                    break;
                case CommandType::PSYNC:
                    command_ptr=make_unique<PsyncCommand>(tokens);
                    break;
                default:
                    break;
                }
                return command_ptr;
            }
        }
        cerr<<"unknown array string command"<<endl;
        return nullptr;
    }
    
    static unique_ptr<ReMessage> parse_simple_message(char* message,int len){
        //解析simple_string格式的消息
        int end=0;
        while(end < len && message[end]!='\r' && message[end]!='\n'){
            end++;
        }

        string str(message,end);
        auto it=remessage_map.find(str);
        if(it!=remessage_map.end()){
            switch (it->second)
            {
            case ReMessageType::PONG:
                return make_unique<ReMessage>(ReMessageType::PONG);
            case ReMessageType::OK:
                return make_unique<ReMessage>(ReMessageType::OK);
            default:
                break;
            }
        }else{
            return make_unique<ReMessage>(ReMessageType::UNKNOWN);
        }
        return nullptr;
    }
public:

    static unique_ptr<Command> parse_message(char* message,int len){
        //解析客户端发送的消息
        char *p=message;
        message++;
        switch (*p)
        {
        case '*':
            return parse_bulk_message(message,len);
            break;
        case '+':
            
            break;
        default:
            break;
        }
        return nullptr;
    };

    static unique_ptr<ReMessage> parse_re_message(char* message,int len){
        //解析re_message格式的消息
        char *p=message;
        message++;
        switch (*p)
        {
        case '*':
            break;
        case '+':
            return parse_simple_message(message,len);
            break;
        default:
            break;
        }
        return nullptr;
    }


};

